home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / snip9611.zip / MYSTREAM.CPP < prev    next >
C/C++ Source or Header  |  1996-11-24  |  4KB  |  145 lines

  1. // +++Date last modified: 02-Nov-1995
  2.  
  3. // Mystream.cpp
  4. // Implementation of ios interface classes for Myio
  5. //
  6. // Written by David L. Nugent
  7. //
  8.  
  9. # include <iostream.h>
  10. # include "Mystream.h"
  11. # if defined(_MSC_VER)
  12. #  include <memory.h>
  13. # else
  14. #  include <stdlib.h>
  15. # endif
  16.  
  17.     // Mystreambuf constructor
  18.     // This simply initialises the base class streambuf
  19.     // (it is initially empty with no buffer allocated)
  20.     // and register the Myio object
  21.     // Note: we _could_ set the stream unbuffered here,
  22.     // which is useful for stdio handles, so that the
  23.     // streambuf functions overflow() and underflow()
  24.     // get called on every character rather than when
  25.     // the streambuf buffer is full
  26.  
  27. Mystreambuf::Mystreambuf (Myio * mPtr)
  28.     : streambuf (), mptr(mPtr)
  29. {
  30. //  unbuffered(1);  // Uncomment to make unbuffered
  31. }
  32.  
  33.     // Mystreambuf()
  34.     // Called when streambuf owned buffer is full
  35.     // or when stream is flushed
  36.     // Our job here is to empty the streambuf
  37.     // write buffer and reset the 'put' pointers.
  38.  
  39. int
  40. Mystreambuf::overflow (int c)
  41. {
  42.     int written;
  43.  
  44.         // Handle unbuffered stream
  45.  
  46.     if (unbuffered())       // Handle the simple case first
  47.     {
  48.         if (c == EOF)   // Special case, this only flushes
  49.             return 0;
  50.         char ch = char(c);  // Write the byte directly
  51.         written = mptr->write (&ch, 1);
  52.         return (written) ? c : EOF;
  53.     }
  54.  
  55.         // Handle buffered stream
  56.  
  57.     if (!base())        // Need to allocate a buffer
  58.         allocate();
  59.  
  60.     if (base())         // Test for memory allocation error
  61.     {
  62.         char * ep = base() + (blen() / 2);
  63.         if (!pbase())   // Set put pointers if not set up
  64.             setp (base(), ep);
  65.         int bytes = pptr() - pbase();   // Bytes to write
  66.         if (bytes)
  67.         {
  68.             written = mptr->write (pbase(), bytes);
  69.             if (!written)
  70.                 return EOF;
  71.             bytes += written;
  72.             if (bytes)  // Some is still waiting to be written
  73.                 memcpy (base(), base() + written, bytes);
  74.         }
  75.         setp (base() + bytes, ep);  // Reset 'put' pointers
  76.         return (c == EOF) ? 0 : sputc (c);  // Put pending chr in buf
  77.     }
  78.     return EOF;
  79. }
  80.  
  81.     //
  82.     // underflow() indicates that the input queue
  83.     // is empty and needs more data
  84.     //
  85.  
  86. int
  87. Mystreambuf::underflow (void)
  88. {
  89.     int bytes;
  90.  
  91.         // Handle an unbuffered stream
  92.  
  93.     if (unbuffered())
  94.     {
  95.         bytes = mptr->read (&_back[1], 1);
  96.         if (!bytes)
  97.         {
  98.             setg (0, 0, 0);
  99.             return EOF;
  100.         }
  101.         setg (_back, _back + 1, _back + 2);
  102.         return (unsigned char)_back[1];
  103.     }
  104.  
  105.         // Handle a buffered stream
  106.  
  107.     if (!base())        // Need to allocate a buffer
  108.         allocate();
  109.  
  110.     if (base())
  111.     {
  112.         char * gp = base() + blen() / 2;
  113.         if (gptr() >= egptr())
  114.         {                   // Read into the buffer from stream
  115.             overflow ();    // Flush output in case we need it
  116.             bytes = mptr->read (gp + 1, blen() / 2 - 1);
  117.             setg (gp, gp + 1, gp + bytes + 1);
  118.         }
  119.         if (gptr() < egptr())   // Get from buffer
  120.             return (unsigned char) *gptr();
  121.     }
  122.     return EOF;
  123. }
  124.  
  125.     //
  126.     // sync() needs to empty both put and get
  127.     // buffered. It will do this by calling
  128.     // overflow and simply resetting the get
  129.     // pointers to their default location.
  130.     //
  131.  
  132. int
  133. Mystreambuf::sync (void)
  134. {
  135.     if (!unbuffered())
  136.     {
  137.         overflow ();                // Force output
  138.         char * gp = base();
  139.         setp (gp, gp + blen() / 2);
  140.         gp = base() + blen() / 2;
  141.         setg (0, 0, 0);
  142.     }
  143.     return 0;
  144. }
  145.